using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System;
using Hope;
using DataFramework;
using ProtoDef.Tutoial;
/// <summary>
/// <para>教学管理类</para>
/// </summary>
public class TutorialManager : MonoSingleton<TutorialManager>
{
    #region    常量定义
    public const string endstag = "ends";
    public const string emptyTag = "empty";

    /// <summary>
    /// <para>教学脚本存储路径</para>
    /// </summary>
    public static string TutorialScriptPath = "Tutorial/Scripts/";

    #endregion 常量定义

    #region script manage

    private bool canStart = false;

    /// <summary>
    /// <para>当前正在运行的教学脚本</para>
    /// </summary>
    TutorialScript _currentScript = null;

    TutorialEventConfig _currentConfig = null;

    /// <summary>
    /// <para>教学脚本正常结束时的回调</para>
    /// </summary>
    Action _callback;

    /// <summary>
    /// 存储处理器的字典
    /// </summary>
    Dictionary<int, BasePlayerEventHandle> handleDict = new Dictionary<int, BasePlayerEventHandle>();


    HashSet<int> completeTutorial = new HashSet<int>();

    public Action lateUpdate;

    public bool TutorialIsDone
    {
        get
        {
            return tutorialIsDone;
        }
    }

    private bool tutorialIsDone = false;


    /// <summary>
    /// 引导的键值
    /// </summary>
    public const string tutorialKey = "tutorial";

    /// <summary>
    /// 初始化
    /// </summary>
    public void Init()
    {
        this.handleDict.Clear();
        var lists = TutorialEventConfig.dataList;
        for (int i = 0; i < lists.Count; i++)
        {
            if (!GetTutoialEventIsComplete(lists[i]))
            {
                var hanlde = PlayerEventFactory.GetEventHandle(lists[i], this.OnHandleHit, lists[i]);
                this.handleDict.Add(lists[i].id, hanlde);
            }
        }
    }

	public override void Reset()
	{
		StopTutorial();
		canStart = false;
		_callback = null;
		handleDict.Clear();
		completeTutorial.Clear();
		lateUpdate = null;
		tutorialIsDone = false;
		PlayerEventCenter.ClearAll();
	}

    public void InitWithProto(ScGetTutorialInfo info)
    {
        completeTutorial.Clear();
        foreach (var item in handleDict)
        {
            item.Value.DeInit();
        }

        var list = info.tutorial_info.finished_ids;
        for (int i = 0; i < list.Count; i++)
        {
            completeTutorial.Add(list[i]);
        }
        if (info.tutorial_info.cur_tutorial_id != 0)
        {
            _currentConfig = TutorialEventConfig.GetByID(info.tutorial_info.cur_tutorial_id);
        }
        Init();
        ///关心玩家进入世界的事件， 响应优先级为特别高级
        PlayerEventCenter.AddEventHandle(PlayerEventDefine.Player_Enter_World, OnPlayerEnterWorld, 999);
    }

    public void OnPlayerEnterWorld(EventHandleArgs args) {
        canStart = true;
        if(_currentConfig != null)
        {
            StartTutorial(_currentConfig.scriptPath);
        }
    }


    /// <summary>
    /// 获取存储的新手引导的字符串
    /// </summary>
    /// <returns></returns>
    protected string GetTutorialSaveString()
    {
        string ret = "";
        foreach (var item in this.completeTutorial)
        {
            ret += item + ";";
        }
        return ret;
    }

    /// <summary>
    /// 获取引导是否完成
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    protected bool GetTutoialEventIsComplete(TutorialEventConfig data)
    {
        if (completeTutorial.Contains(data.id))
        {
            // 临时代码： 如果这里是服务器标识的新手引导结束， 那么为结束.
            if(data.needReset == 0)
            {
                tutorialIsDone = true;
            }
            return true;
        }
        return false;
    }

    /// <summary>
    /// 事件触发，且条件满足
    /// </summary>
    /// <param name="data"></param>
    protected void OnHandleHit(EventHandleData data)
    {
        TutorialEventConfig config = (TutorialEventConfig)data.extenData;
        if (_currentConfig != null)
        {
            if ( config.id == _currentConfig.id)
            {
                return;
            }
            Debug.LogErrorFormat(" Tutorial is Running: ID: {0}, Path: {1}", config.id, config.scriptPath);
            return;
        }
        handleDict.Remove(config.id);
        TutorialProxy.StartTutorial(config.id);
    }

    /// <summary>
    /// <para>启动教学脚本</para>
    /// </summary>
    public bool StartTutorial(string name, Action callback = null)
	{
        if (!GameConfig.Instance.openTutorial)
        {
            return true;
        }
        
		if (this._currentScript != null) {
            Debug.LogWarning("Warning! There's already a tutorial running.");
            return false;
		}

		var asset = Resources.Load<TextAsset>(Path.Combine(TutorialScriptPath, name));
		if (asset != null) {
            this._callback = callback;
			Debug.Log("Tutorial starts: " + name);
            this._currentScript = TutorialScript.LoadFromJson(asset.text);
            this._currentScript.Name = name;
            this._currentScript.Start(this);
            return true;
		}

		return false;
	}

    public void OnTutorialStart(ScStartTutorial tutorial)
    {
        _currentConfig = TutorialEventConfig.GetByID(tutorial.tutorial_id);
        if(_currentConfig == null)
        {
            Debug.LogError("currentConfig is Null, Id is :" + tutorial.tutorial_id);
            return;
        }
        StartTutorial(_currentConfig.scriptPath);
    }

	/// <summary>
	/// <para>停止教学脚本</para>
	/// </summary>
	public void StopTutorial()
	{
		if (this._currentScript != null) {
			Debug.Log("Tutorial is stopped: " + this._currentScript.Name);
            this._currentScript.Stop();
		}
        this._currentScript = null;
        this._currentConfig = null;
        this._callback = null;
	}

	/// <summary>
	/// <para>教学脚本正常结束</para>
	/// </summary>
	public void Ends()
	{
        var config = this._currentConfig;

        if (this._currentScript != null) {
            Debug.Log("Tutorial ends: " + this._currentScript.Name);
            this._currentScript = null;
            this._currentConfig = null;
			if (config != null)
	            TutorialProxy.FinishTutorial(config.id);

        }
		if (this._callback != null) {
			var callback = this._callback;
            this._callback = null;
			callback();
		}
	}

    /// <summary>
    /// 当一个引导脚本结束, 需要做一些处理
    /// </summary>
    /// <param name="script"></param>
    public void OnScriptEnd(int tutorialID)
    {
        var config = TutorialEventConfig.GetByID(tutorialID);
        if(config.needReset == 0)
        {
            tutorialIsDone = true;
        }
        PlayerEventCenter.DispathMessage(PlayerEventDefine.Player_Complete_Tutorial, EventHandleArgs.Get( Req.userInfo, config.scriptPath));
    }



    public void LateUpdate()
    {
        if (lateUpdate != null)
            lateUpdate();
    }

    /// <summary>
    /// 存储当前已完成的引导
    /// </summary>
    private void SaveCurrentTutorial()
    {
        if (this._currentConfig != null)
        {
            PlayerPrefs.SetString(tutorialKey, string.Format("{0};{1}", GetTutorialSaveString(), this._currentConfig.id));
            Debug.Log("Complete Tutorial:  " + this._currentConfig.id);
        }
    }

	#endregion
}